package com.pshcp.service;

import cn.hutool.core.date.DateUtil;
import com.framework.thread.ReqComHold;
import com.framework.util.SystemUtil;
import com.pshcp.common.enums.ReCallHisEnum;
import com.pshcp.common.enums.RegPayStatusEnum;
import com.pshcp.common.enums.RegStatusEnum;
import com.pshcp.common.enums.UnPayNotifyEnum;
import com.pshcp.domain.dto.DoctorOrderCountDTO;
import com.pshcp.domain.dto.OrderRegDTO;
import com.pshcp.domain.model.OrderReg;
import com.pshcp.mapper.OrderRegMapper;

import com.github.pagehelper.PageHelper;
import com.framework.base.PageList;
import com.framework.tool.CommonTool;
import com.pshcp.common.enums.CommonStatusEnum;

import org.aspectj.weaver.ast.Or;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;

/**
 * <p>
 * 挂号订单 服务实现类
 * </p>
 *
 * @author auto generator
 * @since 2022-11-02
 */
@Service
public class OrderRegService {

    @Autowired
    private OrderRegMapper orderRegMapper;

    /**
     * 待出诊挂号单
     * @return
     */
    public List<OrderReg> waitRegOrder(){
        Example example = new Example(OrderReg.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("status", CommonStatusEnum.INIT.getCode());
        criteria.andEqualTo("patientUserId", ReqComHold.getReqCom().getUserId());
        criteria.andGreaterThanOrEqualTo("schDate", DateUtil.today());
        return orderRegMapper.selectByExample(example);
    }

    /**
     * 重试退号的订单
     * @return
     */
    public List<OrderReg> refundRetryList(){
        Example example = new Example(OrderReg.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("status", CommonStatusEnum.INIT.getCode());
        criteria.andEqualTo("reCallHis", ReCallHisEnum.REFUND_FAIL.getCode());
        criteria.andGreaterThan("schDate", DateUtil.today());
        example.setOrderByClause(" created_time limit 15");
        return orderRegMapper.selectByExample(example);
    }

    /**
     * 发起退款的订单
     * @return
     */
    public List<OrderReg> refundPayFeeList(){
        Example example = new Example(OrderReg.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("status", CommonStatusEnum.INIT.getCode());
        criteria.andEqualTo("payStatus", RegPayStatusEnum.LAUNCH_REFUND.getCode());
        example.setOrderByClause(" created_time limit 15");
        return orderRegMapper.selectByExample(example);
    }


    /**
     * 发起退款的订单
     * @return
     */
    public List<OrderReg> refundingList(){
        Example example = new Example(OrderReg.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("status", CommonStatusEnum.INIT.getCode());
        criteria.andEqualTo("payStatus", RegPayStatusEnum.REFUND_ING.getCode());
        example.setOrderByClause(" created_time limit 15");
        return orderRegMapper.selectByExample(example);
    }

    /**
     * 未支付&未消息通知的订单
     * @return
     */
    public List<OrderReg> unPayList(Date timeoutTime){
        Example example = new Example(OrderReg.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("status", CommonStatusEnum.INIT.getCode());
        criteria.andEqualTo("payStatus", RegPayStatusEnum.WAIT_PAY.getCode());
        criteria.andEqualTo("unPayNotify", UnPayNotifyEnum.NO.getCode());
        criteria.andGreaterThan("schDate", DateUtil.today());
        criteria.andLessThanOrEqualTo("createdTime", timeoutTime);
        example.setOrderByClause(" created_time limit 15");
        return orderRegMapper.selectByExample(example);
    }

    /**
     * 超时未支付的订单
     * @return
     */
    public List<OrderReg> unPayTimeoutList(Date timeoutTime){
        Example example = new Example(OrderReg.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("status", CommonStatusEnum.INIT.getCode());
        criteria.andEqualTo("payStatus", RegPayStatusEnum.WAIT_PAY.getCode());
        criteria.andGreaterThan("schDate", DateUtil.today());
        criteria.andLessThanOrEqualTo("createdTime", timeoutTime);
        example.setOrderByClause(" created_time limit 15");
        return orderRegMapper.selectByExample(example);
    }

    /**
     * 当前医生挂号量
     * @param doctorId
     * @return
     */
    public int doctorRegCount(Long doctorId){
        OrderRegDTO orderRegDTO = new OrderRegDTO();
        orderRegDTO.setDoctorId(doctorId);
        orderRegDTO.setStatus(CommonStatusEnum.INIT.getCode());
        return listCount(orderRegDTO);
    }

    /**
     * 医生被挂号数量
     * @param doctorIds
     * @return
     */
    public List<DoctorOrderCountDTO> countByDoctorIds(List<Long> doctorIds){
        return orderRegMapper.countByDoctorIds(doctorIds);
    }

    public PageList<OrderReg> list(OrderRegDTO orderRegDTO){
        if(orderRegDTO.getPageNum() != null && orderRegDTO.getPageSize() != null){
            PageHelper.startPage(orderRegDTO.getPageNum(), orderRegDTO.getPageSize());
        }
        Example example = new Example(OrderReg.class);
        Example.Criteria criteria = example.createCriteria();
        if(orderRegDTO.getStatus() != null){
            criteria.andEqualTo("status", orderRegDTO.getStatus());
        }
        if(orderRegDTO.getPatientUserId() != null){
            criteria.andEqualTo("patientUserId", orderRegDTO.getPatientUserId());
        }
        if(orderRegDTO.getStartTime() != null){
            criteria.andGreaterThanOrEqualTo("createdTime", orderRegDTO.getStartTime());
        }
        if(orderRegDTO.getEndTime() != null){
            criteria.andLessThanOrEqualTo("createdTime", orderRegDTO.getEndTime());
        }
        example.setOrderByClause(" created_time desc");
        List<OrderReg> list = orderRegMapper.selectByExample(example);
        return CommonTool.buildPageList(list);
    }

    public int listCount(OrderRegDTO orderRegDTO){
        Example example = new Example(OrderReg.class);
        Example.Criteria criteria = example.createCriteria();
        if(orderRegDTO.getStatus() != null){
            criteria.andEqualTo("status", orderRegDTO.getStatus());
        }
        if(orderRegDTO.getDoctorId() != null){
            criteria.andEqualTo("doctorId", orderRegDTO.getDoctorId());
        }
        return orderRegMapper.selectCountByExample(example);
    }

    public List<OrderReg> select(OrderReg orderReg){
        return orderRegMapper.select(orderReg);
    }

    public int insert(OrderReg orderReg){
        orderReg.setId(SystemUtil.getId());
        orderReg.setStatus(CommonStatusEnum.INIT.getCode());
        orderReg.setCreatedTime(new Date());
        return orderRegMapper.insert(orderReg);
    }

    public int update(OrderReg orderReg){
        orderReg.setUpdateTime(new Date());
        return orderRegMapper.updateByPrimaryKeySelective(orderReg);
    }

    public OrderReg findById(Long id){
        return orderRegMapper.selectByPrimaryKey(id);
    }

    public List<OrderReg> findByIds(List<Long> ids){
        Example example = new Example(OrderReg.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("id", ids);
        return orderRegMapper.selectByExample(example);
    }

    public int delById(Long id){
        Example example = new Example(OrderReg.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("id", id);

        OrderReg orderReg = new OrderReg();
        orderReg.setStatus(CommonStatusEnum.DEL.getCode());
        return orderRegMapper.updateByExampleSelective(orderReg, example);
    }

}
